﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Galaxy.ModuleInterface.Messages.Destination
{
    /// <summary>Пункт назначения сообщения</summary>
    [Serializable]
    public class CDestination : IDestination, ICloneable, ISerializable
    {
        /* ---------------------------------------------------------------------- */

        private List<string> fNameDistinationList = new List<string>();
        private List<IGalaxyModule> fModuleDistinationList = new List<IGalaxyModule>();

        /* ---------------------------------------------------------------------- */

        public CDestination() { }

        public CDestination(params IGalaxyModule[] Module) { Add(Module); }

        public CDestination(params string[] ModuleName) { Add(ModuleName); }

        public CDestination(IGalaxyModule Module) { Add(Module); }

        protected CDestination(SerializationInfo info, StreamingContext context)
        {
            int lv_Count = info.GetInt32("Count");
            for(int i = 0; i < lv_Count; i++)
                fNameDistinationList.Add(info.GetString("Destination " + i.ToString()));
        }

        /* ---------------------------------------------------------------------- */

        public void Add(params IGalaxyModule[] Module)
        {
            fModuleDistinationList.AddRange(Module);
        }

        public void Add(params string[] ModuleName)
        {
            fNameDistinationList.AddRange(ModuleName);
        }

        public bool Remove(IGalaxyModule Module)
        {
            return fModuleDistinationList.Remove(Module);
        }

        public bool Remove(string ModuleName)
        {
            return fNameDistinationList.Remove(ModuleName);
        }

        public void Clear()
        {
            fNameDistinationList.Clear();
            fModuleDistinationList.Clear();
        }

        public virtual bool Check(IGalaxyModule Module)
        {
            if(fNameDistinationList.Count == 0 && fModuleDistinationList.Count == 0)
                return true;

            if(fModuleDistinationList.Contains(Module)) return true;
            return fNameDistinationList.Find(delegate(string Name) { return Name == Module.Name; }) != null;
            //return false;
        }

        public virtual bool Check(string ModuleName)
        {
            if(fNameDistinationList.Count == 0 && fModuleDistinationList.Count == 0)
                return true;

            if(fNameDistinationList.Contains(ModuleName)) return true;
            return fModuleDistinationList.Find(delegate(IGalaxyModule Module)
            {
                return Module.Name == ModuleName;
            }) != null;
            //for(int i = 0; i < fModuleDistinationList.Count; i++)
            //    if(fModuleDistinationList[i].Name == ModuleName)
            //        return true;
            //return false;
        }

        /* ---------------------------------------------------------------------- */

        public override bool Equals(object obj)
        {
            if(obj is string) return Check(obj as string);
            if(obj is IGalaxyModule) return Check(obj as IGalaxyModule);
            if(obj is CDestination)
                return obj.GetHashCode() == this.GetHashCode();

            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            if(fNameDistinationList.Count == 0 && fModuleDistinationList.Count == 0)
                return base.GetHashCode();
            return fModuleDistinationList.GetHashCode() ^
                fNameDistinationList.GetHashCode();
        }

        public override string ToString()
        {
            StringBuilder Result = new StringBuilder();

            for(int i = 0; i < fNameDistinationList.Count; i++)
                Result.Append(fNameDistinationList[i] + "; ");

            for(int i = 0; i < fModuleDistinationList.Count; i++)
                Result.Append(fModuleDistinationList[i].ToString() + "; ");

            if(Result.ToString() == "") return "Все";

            return Result.ToString();
        }

        public object Clone()
        {
            CDestination Distination = (CDestination)this.MemberwiseClone();

            return Distination;
        }

        /* ---------------------------------------------------------------------- */

        #region ISerializable Members

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Count", fNameDistinationList.Count + fModuleDistinationList.Count);
            int j = 0;
            for(int i = 0, i_Length = fNameDistinationList.Count; i < i_Length; i++, j++)
                info.AddValue("Destination " + j.ToString(), fNameDistinationList[i]);
            for(int i = 0, i_Length = fModuleDistinationList.Count; i < i_Length; i++)
                info.AddValue("Destination " + j.ToString(), fModuleDistinationList[i].Name);
        }

        #endregion
    }
}
